package com.zxl.working.service.impl;

import com.google.gson.Gson;
import com.zxl.working.entity.ErrorMsg;
import com.zxl.working.entity.admin.SysUser;
import com.zxl.working.entity.admin.SysUserAuthority;
import com.zxl.working.entity.backend.*;
import com.zxl.working.entity.dto.SellerAmountData;
import com.zxl.working.entity.dto.SellerRechargeInfo;
import com.zxl.working.entity.dto.SellerTradeDetailsDto;
import com.zxl.working.entity.dto.ServiceInvoice;
import com.zxl.working.mapper.admin.UserMapper;
import com.zxl.working.mapper.backend.*;
import com.zxl.working.service.SellerService;
import com.zxl.working.utils.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class SellerServiceImpl implements SellerService {

    private Logger logger = LogManager.getLogger(SellerServiceImpl.class);
    @Resource
    private SellerMapper sellerMapper;
    @Resource
    private SellerProjectMapper sellerProjectMapper;
    @Resource
    private SellerProjectPersonMapper sellerProjectPersonMapper;
    @Resource
    private PersonInfoMapper personInfoMapper;
    
    @Value("${request.url}")
    private String requestUrl;
    
    @Autowired
    private HttpUtil httpUtil;

    @Resource
    private UserMapper userMapper;

    static String code_regex = "\\d{15}(\\d{2}[0-9xX])?";//身份证验证
    static String phone_regex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[0-9])\\d{8}$";//手机号码验证
    @Resource
    private Gson gson;
    @Resource
    private CommUtil commUtil;
    @Resource
    private FileUitl fileUitl;
    @Resource
    private SerialNoUtil serialNoUtil;
    @Resource
    private SellerAccountDetailMapper sellerAccountDetailMapper;

    @Value("${local.filePath}")
    private String filePath;

    @Value("${local.fileUrl}")
    private String fileUrl;


    private SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public String qryUploadDetails(String sellerId,String params){
        Map<String,String> paramMap = gson.fromJson(params,Map.class);
        int page = Integer.parseInt(paramMap.getOrDefault("page", "0"));
        int pageSize = Integer.parseInt(paramMap.getOrDefault("pageSize", "10"));
        List<SellerUploadDetail> details = sellerMapper.qryDetails(sellerId,page,pageSize);
        int total = sellerMapper.qryDetailsTotal();

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("total",total);
        resMap.put("list",details);
        return commUtil.returnSuccess(resMap);
    }

    public String insUploadDetails(SysUser sysUser, SellerUploadDetail uploadDetail){

        String id = serialNoUtil.genSerialNo("C",sysUser.getPlatform(),sysUser.getMerchantNumber());
        

//        uploadDetail.setId(commUtil.getId());
        uploadDetail.setId(id);
        uploadDetail.setInvestSerial(uploadDetail.getId());
        AgentSellerRelation relation = sellerMapper.qrySellerR(uploadDetail.getSellerAccountId());
//        Double serviceAmount = uploadDetail.getInvestAmount()*relation.getServerAmountPoint()/100;
        Double serviceAmount = 0.0;
        if(relation.getServiceFormula() == 1){
        	 serviceAmount = uploadDetail.getInvestAmount()*relation.getServerAmountPoint()/100/(1+relation.getServerAmountPoint()/100);        	
        }else if(relation.getServiceFormula() == 2){
        	 serviceAmount = uploadDetail.getInvestAmount()*relation.getServerAmountPoint()/100;
        }else{
        	serviceAmount = uploadDetail.getInvestAmount()*relation.getServerAmountPoint()/100/(1+relation.getServerAmountPoint()/100);  
        }
        BigDecimal bd = new BigDecimal(serviceAmount.toString());
        uploadDetail.setServiceAmount(bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
        uploadDetail.setStatus(0);
        sellerMapper.insUploadDetail(uploadDetail);

        return commUtil.returnSuccess(uploadDetail.getId());
    }

    public String qryInvoice(String sellerId,String params){
        Map<String,String> paramMap = gson.fromJson(params,Map.class);
        int page = Integer.parseInt(paramMap.getOrDefault("page", "1"));
        int pageSize = Integer.parseInt(paramMap.getOrDefault("pageSize", "10"));
        Integer start = (page-1)*pageSize;
        List<SellerUploadDetail> details = sellerMapper.qryInvoice(sellerId,start,pageSize);
        int total = sellerMapper.qryInvoiceCnt(sellerId);

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("list",details);
        resMap.put("total",total);

        return commUtil.returnSuccess(resMap);
    }

    public String qrySuccInvoice(String sellerId,String params){
        Map<String,String> paramMap = gson.fromJson(params,Map.class);
        int page = Integer.parseInt(paramMap.getOrDefault("page", "1"));
        int pageSize = Integer.parseInt(paramMap.getOrDefault("pageSize", "10"));
        int start = (page - 1)* pageSize;
        List<SellerUploadDetail> details = sellerMapper.qrySuccInvoice(sellerId,start,pageSize);
        int total = sellerMapper.qryInvoiceSuccCnt(sellerId);

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("list",details);
        resMap.put("total",total);

        return commUtil.returnSuccess(resMap);
    }

    public String qryRechargeInfos(String sellerId){
        List<SellerRechargeInfo> infos = sellerMapper.rechargeInfos(sellerId);

        return commUtil.returnSuccess(infos);
    }

    public String qryAccounts(String sellerId,String params){
        List<SellerAccount> accounts = sellerMapper.qryAccounts(sellerId);
       for(SellerAccount sa : accounts){
           Double investTotal = sa.getInvestTotal()==null?0:sa.getInvestTotal();
           Double serverAmount = sa.getServerAmount()==null?0:sa.getServerAmount();
           Double sendAmount = sa.getSendAmount()==null?0:sa.getSendAmount();
           Double systemAdd = sa.getSystemAdd()==null?0:sa.getSystemAdd();
           Double systemDel = sa.getSystemDel()==null?0:sa.getSystemDel();
           sa.setAccountTotal(systemAdd+investTotal-serverAmount-sendAmount-systemDel);
       }
        return commUtil.returnSuccess(accounts);
    }

    public String qryServiceTypeBySellerId(String sellerId){
        String serviceTypes = sellerMapper.qryServiceTypeBySellerId(sellerId);

        return commUtil.returnSuccess(serviceTypes);
    }

    public String qryAmountBySellerId(String sellerId){
        SellerAmountData sellerAmountData = sellerMapper.qryAmount(sellerId);

        return commUtil.returnSuccess(sellerAmountData);
    }

    public String qryTradeDetails(String sellerId){
        List<SellerTradeDetailsDto> detailsDtos = sellerMapper.qryTradeDetails(sellerId);

        return commUtil.returnSuccess(detailsDtos);
    }



    @Transactional(rollbackFor=Exception.class)
    public String insFee(SysUser sysUser,String fileName, String path, String sellerId, String sellerName, String serviceName, String serviceId,String reportFile){
        String errorMsg="";
        Map<Integer,List<Integer>> errorMap= new HashMap<Integer,List<Integer>>();
        try {
            //查询当前是否是老商户
            SellerInfo sellerInfo=sellerMapper.qrySellerInfoBySellerId(sellerId);


            AgentSellerRelation relation = sellerMapper.qrySellerR(sellerId);
            if (ObjectUtils.isEmpty(relation)) {
                return commUtil.returnStr(-2, "无代理商关系", "");
            }
            AgentAccount account = sellerMapper.qryAgentAccount(relation.getAgentId());
            if (ObjectUtils.isEmpty(account)) {
                return commUtil.returnStr(-2, "无对应代理商", "");
            }

            List<ProvideDetail> provideDetails = fileUitl.readExcel(path);
            if (provideDetails!=null && provideDetails.size() > 20000) {
                return commUtil.returnStr(-3, "上传表格条数不能超过2万条", "");
            }
            String orderId = serialNoUtil.genSerialNo("F",sysUser.getPlatform(),sysUser.getMerchantNumber());/*commUtil.getId();*/

            Double totalFee = 0.0;
            Boolean succRules = true;

            String provideDetailId=serialNoUtil.genSerialNo("Q",sysUser.getPlatform(),sysUser.getMerchantNumber());
            String before = "";
            String after = "";
            String _serial = "";
                String temp = provideDetailId.substring(14,15);
                //如果数据库中该商户当日已经存在订单，计算新的订单号
                if (temp.equals("0")) {
                    //如果最后一位是0则往前多截取一位
                    _serial = provideDetailId.substring(13);
                    before = provideDetailId.substring(0, 13);
                } else {
                    //截取天数最后一位
                    _serial = provideDetailId.substring(14);
                    before = provideDetailId.substring(0, 14);
                }
                int serial = Integer.parseInt(_serial);
                /*拆分数据*/
            int rowNumber=1;
            List<ErrorMsg> errorList= new ArrayList<ErrorMsg>();
            for (ProvideDetail provideDetail : provideDetails) {
                String msg="";
                /*String rowMsg="第"+rowNumber+++"行错误信息：";*/
                provideDetail.setAskTime(new Date());
                provideDetail.setOrderId(orderId);
                provideDetail.setTradeSerial(System.currentTimeMillis() + Math.round(Math.random() * 1000));
                provideDetail.setFbalanceSerial(System.currentTimeMillis() + Math.round(Math.random() * 1000));
                provideDetail.setPayeeAccount(provideDetail.getPayeeAccount().replace(" ", "").replace("　", ""));//卡号去空格
                provideDetail.setPayeeName(provideDetail.getPayeeName().replace(" ", "").replace("　", ""));//姓名去空格
                provideDetail.setPayeeMobile(provideDetail.getPayeeMobile().replace(" ", "").replace("　", ""));//手机号去空格
                provideDetail.setCardCode(provideDetail.getCardCode().replace(" ", "").replace("　", ""));//身份证去空格
                totalFee += provideDetail.getPayAmount();
                Double amount = sellerMapper.qryAmountByCode(provideDetail.getCardCode());
                amount=amount==null?0:amount;

                if(sellerInfo==null){
                    return commUtil.returnStr(-2, "未查询到当前商户信息", "");
                }else{
                    //新用户才做数据验证，老用户直接执行
                    if(sellerInfo.getIsOld()!=null && sellerInfo.getIsOld().equals("N")){
                        if(provideDetail.getPayeeName()==null || provideDetail.getPayeeName().equals("")){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,0,"收款方账户名称不能为空;"));
                        }else{
                            PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                            if(personInfo==null || personInfo.getCardStatus()==null || !personInfo.getCardStatus().equals("Y")){
                                errorList.add(new ErrorMsg(rowNumber,0,"此身份证信息未认证，认证后方可添加;"));
                            }else if(!provideDetail.getPayeeName().equals(personInfo.getPersonName())){
                                errorList.add(new ErrorMsg(rowNumber,0,"收款方账户名称与认证身份证名称不对应，请输入正确的名称;"));
                            }
                        }
                        if(provideDetail.getPayeeAccountBankName()==null || provideDetail.getPayeeAccountBankName().equals("")){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,1,"开户行全称不能为空;"));
                        }
                        if(!provideDetail.getCardCode().matches(code_regex)){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,2,"身份证位数不正确;"));
                        }else{
                            int age=matchesAge(provideDetail);
                            if(age<18 ||age >60){
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber,2,"身份证年龄不符合,必须是18到60岁之间;"));
                            }else{
                                PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                                if(personInfo==null || personInfo.getCardStatus()==null || !personInfo.getCardStatus().equals("Y")){
                                    succRules = false;
                                    errorList.add(new ErrorMsg(rowNumber,2,"此身份证信息未认证，认证后方可添加;"));
                                }
                            }
                        }
                        if(provideDetail.getPayeeAccount()==null || provideDetail.getPayeeAccount().equals("")){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,3,"银行账号不能为空;"));
                        }
                        /*验证金额*/
                        if(amount>100000|| provideDetail.getPayAmount()>100000 || (provideDetail.getPayAmount()+amount)>100000){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,4,"单个用户单月发放金额不能超过10万;"));
                        }
                        if(!provideDetail.getPayeeMobile().matches(phone_regex)){
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber,5,"实名手机号错误;"));
                        }else{
                            //验证手机号码唯一性
                            PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                            if(personInfo==null){//无此用户时手机号码必须为未注册过
                                SysUser uu=userMapper.qryUserByLoginName(provideDetail.getPayeeMobile());
                                if(uu!=null){//存在改身份证对应的手机号码，不能操作
                                    succRules = false;
                                    errorList.add(new ErrorMsg(rowNumber,5,"该身份证对应的手机号码已被其他身份证注册，请修改手机号码;"));
                                }

                            }
                        }

                        if(rowNumber==1){//只验证第一行项目信息
                            if(provideDetail.getTitle()==null || provideDetail.getTitle().equals("")){
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber,7,"项目名称不能为空;"));
                            }
                            if(provideDetail.getInfo()==null ||provideDetail.getInfo().equals("")){
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber,8,"项目描述不能为空;"));
                            }
                            if(provideDetail.getName()==null || provideDetail.getName().equals("")){
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber,9,"项目负责人不能为空;"));
                            }
                            if(provideDetail.getPhone()==null ||provideDetail.getPhone().equals("") || !provideDetail.getPhone().matches(phone_regex)){
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber,10,"项目负责人联系方式错误;"));
                            }
                        }else{
                            if(provideDetail.getTitle()==null || provideDetail.getTitle().equals("")){
                                provideDetail.setTitle(provideDetails.get(0).getTitle());
                            }
                            if(provideDetail.getInfo()==null ||provideDetail.getInfo().equals("")){
                                provideDetail.setInfo(provideDetails.get(0).getInfo());
                            }
                            if(provideDetail.getName()==null || provideDetail.getName().equals("")){
                                provideDetail.setName(provideDetails.get(0).getName());
                            }
                            if(provideDetail.getPhone()==null ||provideDetail.getPhone().equals("") || !provideDetail.getPhone().matches(phone_regex)){
                                provideDetail.setPhone(provideDetails.get(0).getPhone());
                            }

                        }
                    }else {
                        //做基础数据验证：
                        if (provideDetail.getPayeeName() == null || provideDetail.getPayeeName().equals("")) {
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber, 0, "收款方账户名称不能为空;"));
                        }
                        if (provideDetail.getPayeeAccountBankName() == null || provideDetail.getPayeeAccountBankName().equals("")) {
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber, 1, "开户行全称不能为空;"));
                        }
                        if (!provideDetail.getCardCode().matches(code_regex)) {
                        	 PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                        	if(personInfo == null || personInfo.getCardCode().equals("")){
                        		succRules = false;
                                errorList.add(new ErrorMsg(rowNumber, 2, "身份证位数不正确;"));
                        	}
                        }
                        if (provideDetail.getPayeeAccount() == null || provideDetail.getPayeeAccount().equals("")) {
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber, 3, "银行账号不能为空;"));
                        }
                        if (!provideDetail.getPayeeMobile().matches(phone_regex)) {
                            succRules = false;
                            errorList.add(new ErrorMsg(rowNumber, 5, "实名手机号错误;"));
                        }else{
                            //验证手机号码唯一性
                            PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                            if(personInfo==null){//无此用户时手机号码必须为未注册过
                                SysUser uu=userMapper.qryUserByLoginName(provideDetail.getPayeeMobile());
                                if(uu!=null){//存在改身份证对应的手机号码，不能操作
                                    succRules = false;
                                    errorList.add(new ErrorMsg(rowNumber,5,"该身份证对应的手机号码已被其他身份证注册，请修改手机号码;"));
                                }

                            }
                        }

                        if (rowNumber == 1) {//只验证第一行项目信息
                            if (provideDetail.getTitle() == null || provideDetail.getTitle().equals("")) {
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber, 7, "项目名称不能为空;"));
                            }
                            if (provideDetail.getInfo() == null || provideDetail.getInfo().equals("")) {
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber, 8, "项目描述不能为空;"));
                            }
                            if (provideDetail.getName() == null || provideDetail.getName().equals("")) {
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber, 9, "项目负责人不能为空;"));
                            }
                            if (provideDetail.getPhone() == null || provideDetail.getPhone().equals("") || !provideDetail.getPhone().matches(phone_regex)) {
                                succRules = false;
                                errorList.add(new ErrorMsg(rowNumber, 10, "项目负责人联系方式错误;"));
                            }
                        } else {
                            if (provideDetail.getTitle() == null || provideDetail.getTitle().equals("")) {
                                provideDetail.setTitle(provideDetails.get(0).getTitle());
                            }
                            if (provideDetail.getInfo() == null || provideDetail.getInfo().equals("")) {
                                provideDetail.setInfo(provideDetails.get(0).getInfo());
                            }
                            if (provideDetail.getName() == null || provideDetail.getName().equals("")) {
                                provideDetail.setName(provideDetails.get(0).getName());
                            }
                            if (provideDetail.getPhone() == null || provideDetail.getPhone().equals("") || !provideDetail.getPhone().matches(phone_regex)) {
                                provideDetail.setPhone(provideDetails.get(0).getPhone());
                            }
                        }
                    }
                }
                provideDetail.setStatus(1);
                rowNumber++;
            }
            if (succRules) {
                List<ProvideDetail> provideDetails1=new ArrayList<ProvideDetail>();
                for (ProvideDetail provideDetail : provideDetails) {
                    /*验证单笔金额不超过3W超过则拆分*/
                    if(provideDetail.getPayAmount()>=50000){
                        double money=provideDetail.getPayAmount();
                        int [] ms= DigitalSplitUtil.splitInto((int)money);
                        for (int i=0;i<ms.length;i++){
                            ProvideDetail p= CreateNewProvideDetail(provideDetail);
                            p.setId(before + serial++);//单号累加
                            //验证金额是否出现小数，如果是则最后一笔加剩余小数
                            if(i==ms.length-1 && (provideDetail.getPayAmount()-DigitalSplitUtil.sum(ms,ms.length))!=0){
                                p.setPayAmount((ms[i]+provideDetail.getPayAmount()-DigitalSplitUtil.sum(ms,ms.length)));
                            }else{
                                p.setPayAmount((double)ms[i]);
                            }
                            provideDetails1.add(p);
                        }
                    }else{
                        provideDetail.setId(before + serial++);//单号累加
                        provideDetail.setTitle(isNull(provideDetail.getTitle())?provideDetails.get(0).getTitle():provideDetail.getTitle());
                        provideDetail.setInfo(isNull(provideDetail.getInfo())?provideDetails.get(0).getInfo():provideDetail.getInfo());
                        provideDetail.setName(isNull(provideDetail.getName())?provideDetails.get(0).getName():provideDetail.getName());
                        provideDetail.setPhone(isNull(provideDetail.getPhone())?provideDetails.get(0).getPhone():provideDetail.getPhone());
                        provideDetails1.add(provideDetail);
                    }
                }
                SellerProvideOrder provideOrder = new SellerProvideOrder();
                provideOrder.setOrderId(orderId);
                provideOrder.setSellerId(sellerId);
                provideOrder.setSellerName(sellerName);
                provideOrder.setServiceId(serviceId);
                provideOrder.setServiceName(serviceName);
                provideOrder.setApplyTime(new Date());
                provideOrder.setProvideList(fileName);
                provideOrder.setRealAmount(totalFee);
                
                double serviceFee = 0.0;
                
                if(relation.getServiceFormula() == 1){
                	serviceFee = totalFee*relation.getServerAmountPoint()/100;
                	//serviceFee = totalFee*relation.getServerAmountPoint()/100/(1+relation.getServerAmountPoint()/100);        	
               }else if(relation.getServiceFormula() == 2){
            	   serviceFee = totalFee*relation.getServerAmountPoint()/100/(1-relation.getServerAmountPoint()/100); 
               }else{
            	   serviceFee = totalFee*relation.getServerAmountPoint()/100;
               }
               // serviceFee = totalFee*relation.getServerAmountPoint()/100;
                double provideAmount = totalFee + serviceFee;
                provideOrder.setProvideAmount(provideAmount);
                provideOrder.setBaseAmountPoint(account.getBaseAmountPoint());
                provideOrder.setServerAmountPoint(relation.getServerAmountPoint());
                provideOrder.setOverAmountPoint(provideOrder.getServerAmountPoint()-provideOrder.getBaseAmountPoint());
                provideOrder.setStepAmountPoint(account.getStepAmountPoint());
                provideOrder.setOrderType(0);
                provideOrder.setReportFile(reportFile);


                sellerMapper.insProvideOrderTemp(provideOrder);//新增主表
                for(ProvideDetail provideDetail: provideDetails1){//循环添加明细
                    provideDetail.setStatus(1);
                    provideDetail.setSellerId(provideOrder.getSellerId());
                    sellerMapper.insProvideDetailsTemp(provideDetail);
                }
                /*
                 *  新商户：支付验证——添加项目信息-需验证个人信息是否存在-如个人信息匹配则添加个人承接项目信息；
                 *  老商户：支付不验证——添加项目信息-不验证个人信息是否存在-不添加个人承接项目信息
                 */
                //发布任务和自动领取任务
                for(ProvideDetail provideDetail: provideDetails){
                    provideDetail.setStatus(1);
                    provideDetail.setSellerId(provideOrder.getSellerId());

                    PersonInfo personInfo= personInfoMapper.qryPersonInfoByCardCode(provideDetail.getCardCode());
                    //如果个人不存在，则创建用户信息
                    if(personInfo==null){
                        //创建用户
                        SysUser user= new SysUser();
                        user.setUserId(commUtil.getId());//主键
                        user.setLoginName(provideDetail.getPayeeMobile());//发放人手机号码
                        user.setUserName(provideDetail.getPayeeName());//发放人名称
                        user.setPassword(MD5Util.getMD5Lower("123456"));//默认密码
                        user.setValid("Y");
                        user.setLastChangePwdTime(sdf.format(new Date()));
                        user.setLimitMultiLogin("Y");
                        user.setCreateTime(new Date());
                        user.setUpdateTime(new Date());
                        userMapper.save(user);
                        //创建菜单
                        SysUserAuthority sysUserAuthority= new SysUserAuthority();
                        sysUserAuthority.setUserAuthorityId(commUtil.getId());
                        sysUserAuthority.setUserId(user.getUserId());
                        userMapper.saveSysUserAuthority(sysUserAuthority);
                        //个人信息新增
                        personInfo=new PersonInfo();
                        personInfo.setPersonId(commUtil.getId());
                        personInfo.setPersonName(provideDetail.getPayeeName());//名称
                        personInfo.setCardType(1);//证件类型
                        personInfo.setCardCode(provideDetail.getCardCode());//身份证
                        personInfo.setMobile(provideDetail.getPayeeMobile());//发放人手机号码
                        //personInfo.setCardStatus("N");//不做验证是否为签约用户
                        personInfo.setAgreement("1");
                        personInfo.setLoginId(user.getUserId());
                        personInfo.setLoginName(user.getLoginName());
                        personInfoMapper.save(personInfo);
                    }

                   /* if(sellerInfo!=null && sellerInfo.getIsOld().equals("N")){*/
                        /*发布任务*/
                        SellerProject sellerProject= new SellerProject();
                        sellerProject.setChargeName(isNull(provideDetail.getName())?provideDetails.get(0).getName():provideDetail.getName());
                        sellerProject.setProjectName(isNull(provideDetail.getTitle())?provideDetails.get(0).getTitle():provideDetail.getTitle());
                        sellerProject.setProjectRequirement(isNull(provideDetail.getInfo())?provideDetails.get(0).getInfo():provideDetail.getInfo());
                        sellerProject.setSellerId(provideOrder.getSellerId());
                        sellerProject.setStatus("Y");
                        sellerProject.setTelephone(isNull(provideDetail.getPhone())?provideDetails.get(0).getPhone():provideDetail.getPhone());
                        sellerProject.setCreatedTime(new Date());
                        sellerProject.setProjectId(commUtil.getId());
                        sellerProject.setProjectCode(orderId);//发放主键ID
                        sellerProjectMapper.insSellerProject(sellerProject);
                            //承接项目
                            SellerProjectPerson sellerProjectPerson = new SellerProjectPerson();
                            sellerProjectPerson.setCreatedTime(new Date());
                            sellerProjectPerson.setPersonInfoId(personInfo.getPersonId());//承接人ID
                            sellerProjectPerson.setProjectId(sellerProject.getProjectId());
                            sellerProjectPerson.setProjectPersonId(commUtil.getId());
                            sellerProjectPerson.setSellerId(orderId);//发放主键ID
                            sellerProjectPerson.setStatus(1);
                            sellerProjectPersonMapper.insSellerProjectPerson(sellerProjectPerson);

                  /*  }*/

                }
//                sellerMapper.updSellerAccount(provideAmount,provideOrder.getSellerId(),provideOrder.getServiceId());
                Map<String,Object> map = new HashMap<>();
                map.put("totalFee",provideAmount);
                map.put("serviceFee",serviceFee);
                map.put("realFee",totalFee);
                map.put("orderId",orderId);
                if(provideDetails1!=null && provideDetails1.size()>0){
                    for (ProvideDetail p:provideDetails1) {
                        if(isNull(p.getPhone()) ||isNull(p.getName())|| isNull(p.getTitle()) || isNull(p.getInfo())){
                            p.setInfo(provideDetails1.get(0).getInfo());
                            p.setName(provideDetails1.get(0).getName());
                            p.setTitle(provideDetails1.get(0).getTitle());
                            p.setPhone(provideDetails1.get(0).getPhone());
                        }
                    }
                }

                map.put("provideDetails",provideDetails1);
                map.put("order",provideOrder);
                return commUtil.returnSuccess(map);
            } else {
                String[] headName = {"收款方账户名称", "开户行全称", "身份证", "收款方账号", "实发金额", "实名手机号", "款项备注","项目名称","项目描述","项目负责人名称","负责人手机号码"};
                String[] headKey = {"status","payeeName", "payeeAccountBankName", "cardCode", "payeeAccount", "payAmount", "payeeMobile", "payeeRemark","title","info","name","phone"};
                XSSFWorkbook xssfWorkbook = fileUitl.createExcel(errorList,headName, headKey, "错误详细表", provideDetails);
                String fn = "错误列表"+System.currentTimeMillis()+".xlsx";
                FileOutputStream out = new FileOutputStream(filePath + "/" + fn);
                xssfWorkbook.write(out);
                out.close();
                return commUtil.returnStr(-4,"上传文件数据错误",fileUrl+fn);
            }
        }catch (Exception e){
            e.printStackTrace();
           return commUtil.returnStr(-5,"文件解析错误",e.getMessage());
        }
    }

    /**
     * 是否为空 为空位真
     * @param param
     * @return
     */
    public boolean isNull(String param){
        if(param==null){
            return true;
        }else if("".equals(param)){
            return true;
        }
        return false;
    }



    /**
     * 失败交易，插入到明细表，对冲成功明细
     * @param retSellerOrder
     * @param operType -1支出 1收入
     * @param orderSource
     * @param paySubject
     */
    private void generateSellerAccountDetail(SellerProvideOrder retSellerOrder,int operType,String orderSource, String paySubject,String sellerAccountId,String msg) {
        Timestamp now = Timestamp.valueOf(LocalDateTime.now());
        SellerAccountDetails sellerAccountDetailVo = new SellerAccountDetails();
        sellerAccountDetailVo.setTradeId(commUtil.getId());
        sellerAccountDetailVo.setSellerId(retSellerOrder.getSellerId());
        sellerAccountDetailVo.setSellerAccountId(sellerAccountId);
        sellerAccountDetailVo.setTradeSerial(retSellerOrder.getOrderId());
        sellerAccountDetailVo.setServiceId(retSellerOrder.getServiceId());
        sellerAccountDetailVo.setOrderSource(orderSource);
        sellerAccountDetailVo.setOperType(operType);
        sellerAccountDetailVo.setPayTime(now);
        sellerAccountDetailVo.setPaySubject(paySubject);
        sellerAccountDetailVo.setPayType(1);
        sellerAccountDetailVo.setTradeMoney(retSellerOrder.getRealAmount());
        sellerAccountDetailVo.setIsTotal("N");
        sellerAccountDetailVo.setTradeComment(msg);
        sellerAccountDetailVo.setTotalTime(now);
//		sellerAccountDetailVo.setCpmTime(now);
        sellerAccountDetailMapper.insertSellerAccountDetail(sellerAccountDetailVo);
    }


    private ProvideDetail  CreateNewProvideDetail(ProvideDetail provideDetail) {
        ProvideDetail p=new ProvideDetail();
        p.setInfo(provideDetail.getInfo());
        p.setTitle(provideDetail.getTitle());
        p.setStatus(provideDetail.getStatus());
        p.setAskTime(provideDetail.getAskTime());
        p.setCardCode(provideDetail.getCardCode());
        p.setFbalanceSerial(provideDetail.getFbalanceSerial());
        p.setName(provideDetail.getName());
        p.setOrderId(provideDetail.getOrderId());
        p.setPayeeAccount(provideDetail.getPayeeAccount());
        p.setPayeeAccountBankName(provideDetail.getPayeeAccountBankName());
        p.setPayeeMobile(provideDetail.getPayeeMobile());
        p.setPayeeName(provideDetail.getPayeeName());
        p.setPayeeRemark(provideDetail.getPayeeRemark());
        p.setPhone(provideDetail.getPhone());
        p.setTradeSerial(provideDetail.getFbalanceSerial());
        p.setCreateTime(provideDetail.getCreateTime());
        p.setReason(provideDetail.getReason());
        p.setSellerId(provideDetail.getSellerId());
        p.setSellerName(provideDetail.getSellerName());
        p.setServiceId(provideDetail.getServiceId());
        p.setServiceName(provideDetail.getServiceName());
        p.setUpdateTime(provideDetail.getUpdateTime());
        return p;
    }

    private int matchesAge(ProvideDetail provideDetail) {
        Calendar cal = Calendar.getInstance();
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH)+1;
        int dayNow = cal.get(Calendar.DATE);

        int year = Integer.valueOf(provideDetail.getCardCode().substring(6, 10));
        int month = Integer.valueOf(provideDetail.getCardCode().substring(10,12));
        int day = Integer.valueOf(provideDetail.getCardCode().substring(12,14));
        int age=0;
        if ((month < monthNow) || (month == monthNow && day<= dayNow) ){
            age = yearNow - year;
        }else {
            age = yearNow - year-1;
        }
        return age;
    }


    public String subUpData(String params,String sellerName){
        Map<String,String> paramMap = gson.fromJson(params,Map.class);
        if(paramMap.containsKey("orderId")){
            String orderId = paramMap.get("orderId");
            //SellerProvideOrder order = sellerMapper.qryOrder(orderId);
           /* //扣除余额
            String sellerAccountId = sellerAccountDetailMapper.qrySellerAccount(order.getSellerId());
            generateSellerAccountDetail(order,-1,"00","0003",sellerAccountId,"发放支出");
*/
            sellerMapper.insProvideDetails(orderId);
            sellerMapper.insProvideOrder(orderId);
//            sellerMapper.updSellerAccount(order.getProvideAmount(),order.getSellerId(),order.getServiceId());
            String money= sellerMapper.selectByMoney(orderId);
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss");
            /*TODO 发送邮件*/
            httpUtil.get(requestUrl+"/backend/dict/sendMain?flag=3&name="+sellerName + "&money="+money +"&time="+ formatter.format(new java.util.Date()));
            return commUtil.returnSuccess("");
        }else {
            return commUtil.returnStr(-1,"参数缺失","");
        }

    }

    @Override
    public String updateData(String params) {
        Map<String,String> paramMap = gson.fromJson(params,Map.class);
        if(paramMap.containsKey("orderId")){
            String orderId = paramMap.get("orderId");
            SellerProvideOrder order = sellerMapper.qryOrder(orderId);

            try {
                //删除任务
                sellerProjectMapper.deleteByOrderId(orderId);
                //删除承接
                sellerProjectPersonMapper.deleteByOrderId(orderId);
                /*修改订单状态为取消*/
                sellerMapper.updateProvideDetailTemp_status(orderId);
                sellerMapper.updateSellerProvideOrderTemp_status(orderId);
           /* sellerMapper.updateProvideDetail_status(orderId);
            sellerMapper.updateSellerProvideOrder_status(orderId);*/
                sellerMapper.insProvideDetails(orderId);
                sellerMapper.insProvideOrder(orderId);
            }catch (Exception e){
                e.printStackTrace();
            }
            return commUtil.returnSuccess("");
        }else {
            return commUtil.returnStr(-1,"参数缺失","");
        }
    }

    public String qryProvideOrder(String sellerId,String params){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH)-13);
        Map<String,String> qryParam = gson.fromJson(params,Map.class);
        String beginDate = qryParam.getOrDefault("beginDate",commUtil.getDate(calendar.getTime(),"")+" 00:00:00");
        String endDate = qryParam.getOrDefault("endDate",commUtil.getDate(new Date(),"")+" 23:59:59");
        Integer page = Integer.parseInt(qryParam.getOrDefault("page","1"));
        Integer pageSize = Integer.parseInt(qryParam.getOrDefault("pageSize","10"));
        String orderId = StringUtils.isBlank(qryParam.getOrDefault("orderId",null)) ? null : qryParam.getOrDefault("orderId",null);
        String interest = StringUtils.isBlank(qryParam.getOrDefault("interest",null)) ? null : qryParam.getOrDefault("interest",null);
        Integer start = (page - 1)* pageSize;

        List<SellerProvideOrder> orders = sellerMapper.qryOrderBySeller(sellerId,start,pageSize,beginDate,endDate,orderId,interest==null?null:Integer.parseInt(interest));
        Integer cnt = sellerMapper.qryOrderBySellerCnt(sellerId,beginDate,endDate,orderId,interest==null?null:Integer.parseInt(interest));

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("details",orders);
        resMap.put("total",cnt);

        return commUtil.returnSuccess(resMap);
    }

    /**
     * 发放流水
     * @param sellerId
     * @param params
     * @return
     */
    public String qryProvideDetails(String sellerId,String params){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH)-13);
        Map<String,String> qryParam = gson.fromJson(params,Map.class);
        String beginDate = qryParam.getOrDefault("beginDate",commUtil.getDate(calendar.getTime(),"")+" 00:00:00");
        String endDate = qryParam.getOrDefault("endDate",commUtil.getDate(new Date(),"")+" 23:59:59");
        Integer page = Integer.parseInt(qryParam.getOrDefault("page","1"));
        Integer pageSize = Integer.parseInt(qryParam.getOrDefault("pageSize","10"));
        String orderId = StringUtils.isBlank(qryParam.getOrDefault("orderId",null)) ? null : qryParam.getOrDefault("orderId",null);
        String name = StringUtils.isBlank(qryParam.getOrDefault("name",null)) ? null : qryParam.getOrDefault("name",null);
        String account = StringUtils.isBlank(qryParam.getOrDefault("account",null)) ? null : qryParam.getOrDefault("account",null);
        Integer start = (page - 1)* pageSize;

        List<ProvideDetail> details = sellerMapper.qryProvideDetails(sellerId,start,pageSize,beginDate,endDate,orderId,name,account);
        Integer cnt = sellerMapper.qryProvideDetailsCnt(sellerId,beginDate,endDate,orderId,name,account);

        Double totalSend = sellerMapper.qryTotalSend(sellerId);
        Double succSend = sellerMapper.qrySuccTotalSend(sellerId);

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("details",details);
        resMap.put("total",cnt);
        resMap.put("totalSend",totalSend==null?0:totalSend);
        resMap.put("succSend",succSend==null?0.0:succSend);

        return commUtil.returnSuccess(resMap);
    }

    public String needBill(String sellerId,String params){
        Map<String,String> qryParam = gson.fromJson(params,Map.class);
        Integer page = Integer.parseInt(qryParam.getOrDefault("page","1"));
        Integer pageSize = Integer.parseInt(qryParam.getOrDefault("pageSize","10"));
        Integer start = (page - 1)* pageSize;

        List<SellerProvideOrder> orders = sellerMapper.qryNeedBill(sellerId,start,pageSize);
        Integer cnt = sellerMapper.qryNeedBillCnt(sellerId);

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("details",orders);
        resMap.put("total",cnt);

        return commUtil.returnSuccess(resMap);
    }

    public String canProvide(String sellerId,String params){
        Map<String,String> qryParam = gson.fromJson(params,Map.class);
        Integer page = Integer.parseInt(qryParam.getOrDefault("page","1"));
        Integer pageSize = Integer.parseInt(qryParam.getOrDefault("pageSize","10"));
        Integer start = (page - 1)* pageSize;

        List<SellerUploadDetail> orders = sellerMapper.qryCanProvide(sellerId,start,pageSize);
        Integer cnt = sellerMapper.qryNeedBillCnt(sellerId);

        Map<String,Object> resMap = new HashMap<>();
        resMap.put("details",orders);
        resMap.put("total",cnt);

        return commUtil.returnSuccess(resMap);
    }

	@Override
	public String findByMoney(String sellerId) {
		return sellerMapper.findByMoney(sellerId);
	}

	@Override
	public String export(HttpServletResponse resp, String sellerId,String beginDate,String endDate,String orderId,String account,String name) {
		if(name.equals("")){
			name = null;
		}
		if(account.equals("")){
			account = null;
		}
		if(orderId.equals("")){
			orderId=null;
		}
		List<ProvideDetail> details = sellerMapper.qryProvideDetailsExport(sellerId,beginDate,endDate,orderId,account,name);
		ServletOutputStream outputStream = null;
		export(outputStream,details,resp);
		return null;
	}
	
	
	
	private void export(ServletOutputStream outputStream,List<ProvideDetail> all, HttpServletResponse resp) {
		try {
		 //一.创建工作搏
        XSSFWorkbook workbook = new XSSFWorkbook();
        //二.创建工作表
        XSSFSheet sheet = workbook.createSheet("交易流水");
        //设置日期格式
        XSSFCellStyle style = workbook.createCellStyle();
        short fommart = workbook.createDataFormat().getFormat("yyyy年MM月dd日");
        style.setDataFormat(fommart);
        //三.创建行  ---下标为0
        XSSFRow sheetRow = sheet.createRow(0);
        //填充表头
        List<String> splitTitles = new ArrayList<>();
        splitTitles.add("商户名称");
        splitTitles.add("客户订单号");
        splitTitles.add("交易流水号");
        splitTitles.add("请求时间");
        splitTitles.add("收款人姓名");
        splitTitles.add("收款账号");
        splitTitles.add("交易金额");
        splitTitles.add("交易状态");
        
        // Set height of the row
        sheetRow.setHeight((short) 500);
        // Create a new font and alter it.
        XSSFFont font = workbook.createFont();
        //冻结第一行
        sheet.createFreezePane( 0, 1, 0, 1 );
        //处理标题行
        for (int i = 0; i < splitTitles.size(); i++) {
            XSSFCell cell = sheetRow.createCell(i);
            sheetRow.setHeight((short) 500);
            cell.setCellValue(splitTitles.get(i));
            cell.setCellStyle(style);
            if (i < 2) {
                sheet.setColumnWidth(i, 7000);
            } else if (i == 2) {
                sheet.setColumnWidth(i, 5000);
            } else {
                sheet.setColumnWidth(i, 4000);
            }
        }
     // 处理数据行
        for(int i=1;i<=all.size();i++){
        	sheetRow = sheet.createRow(i);
        	if(all.get(i-1).getSellerName() != null){//商户名称
           	 sheetRow.createCell(0).setCellValue(all.get(i-1).getSellerName());
           }
        	if(all.get(i-1).getOrderId() != null){//客户订单号
              	 sheetRow.createCell(1).setCellValue(all.get(i-1).getOrderId());
              }
        	if(all.get(i-1).getId() != null){//交易流水号
              	 sheetRow.createCell(2).setCellValue(all.get(i-1).getId());
              }
        	if(all.get(i-1).getAskTime() != null){//请求时间
              	 sheetRow.createCell(3).setCellValue(DateUtils.formatDate(all.get(i-1).getAskTime(),"yyyy-MM-dd HH:mm:ss"));
              }
        	if(all.get(i-1).getPayeeName() != null){//收款人姓名
              	 sheetRow.createCell(4).setCellValue(all.get(i-1).getPayeeName());
              }
        	if(all.get(i-1).getPayeeAccount() != null){//收款账号
              	 sheetRow.createCell(5).setCellValue(all.get(i-1).getPayeeAccount());
              }
        	if(all.get(i-1).getPayAmount() != null){//交易金额
              	 sheetRow.createCell(6).setCellValue(all.get(i-1).getPayAmount());
              }
        	if(all.get(i-1).getStatus() != null){//交易状态
              	 sheetRow.createCell(7).setCellValue(getStatus(all.get(i-1).getStatus(),all.get(i-1).getPaymentStatus(),all.get(i-1).getPaymentCode(),all.get(i-1).getPaymentMsg()));
              }
        }
        
        
        String format = new SimpleDateFormat("MM-dd").format(new Date());
        // 响应设置
           // 响应头 编码格式ISO8859-1
           resp.setHeader("content-disposition", "attachment;filename="
                   + URLEncoder.encode("交易流水", "utf-8") + "-" + format
                   + ".xlsx");
           // 响应内容
           resp.setContentType("application/vnd.ms-excel");

           // 将workbook输出流的方式下载到客户端
           outputStream = resp.getOutputStream();
           workbook.write(outputStream);

		} catch (Exception e) {
			e.printStackTrace();
	}
	}
	
	public String getStatus(Integer status,String paymentStatus,String paymentCode,String paymentMsg){
		String sum="未知";
		switch(status){
		case 0:
			sum="发放中";
			break;
		case 1:
			if(paymentStatus.equals("N")){
				sum = "发放成功,线下支付";
			}else if(paymentStatus.equals("S")){
				sum = "发放成功,线上支付";
			}else if(paymentStatus.equals("P")){
				sum = "银行处理中";
			}else if(paymentStatus.equals("F") && paymentCode == null){
				sum = "发放失败,支付异常";
			}else if(paymentStatus.equals("F") && paymentCode.equals("1005") || paymentCode.equals("2005")|| paymentCode.equals("4003")|| paymentCode.equals("4012")){
				sum = "发放失败"+paymentMsg;
			}else if(paymentStatus.equals("F") && !paymentCode.equals("1005") || !paymentCode.equals("2005")|| !paymentCode.equals("4003")|| !paymentCode.equals("4012")){
				sum = "发放失败,支付异常";
			}else{
				sum = "发放处理中";
			}
			break;
		case 2:
			sum="取消发放";
			break;
		}
		return sum;
		
	}
}
